﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using MapEditorControlLibrary;
using System.IO;
using System.Xml;
using System.Reflection;
using Catsland.Core;


namespace Catsland.Editor
{
	public partial class MapEditor : Form, IEditor
	{
		GameEngine m_gameEngine;
		AnimationClip.PlayMode[] PlayModeLUT;

        CatsModel m_observingModel;
        Material m_observingMaterial;
        GameObject m_observingGameObject;
        static string m_tmp_filename = "catsengine.tmp";

		public MapEditor()
		{
			InitializeComponent();
			InitializeEditor();
		}

		void InitializeEditor()
		{

			PlayModeLUT = new AnimationClip.PlayMode[4];
			PlayModeLUT[0] = AnimationClip.PlayMode.CLAMP;
			PlayModeLUT[1] = AnimationClip.PlayMode.LOOP;
			PlayModeLUT[2] = AnimationClip.PlayMode.PINGPONG;
			PlayModeLUT[3] = AnimationClip.PlayMode.STOP;
   
		}

        private void menu_insert_component(object sender, EventArgs e)
        {
            if (m_observingGameObject != null)
            {
                string componentName = ((ToolStripMenuItem)sender).Text;

                Type componentType = Mgr<TypeManager>.Singleton.GetCatComponentType(componentName);
                ConstructorInfo constructorInfo = componentType.GetConstructor(new Type[1] { typeof(GameObject) });
                CatComponent component = (CatComponent)constructorInfo.Invoke(new Object[1] { m_observingGameObject });

                m_observingGameObject.AddComponent(componentName, component);
                component.Initialize(Mgr<Scene>.Singleton);
                UpdateGameObjectAttribute(m_observingGameObject);
            }
        }

		public void PostInitializeEditor()
		{
            // add the resource file names into lists
			InitializeResourceList("image", attr_mtrl_texture);
			InitializeResourceList("effect", attr_mtrl_effect);

            // component insert items
            Dictionary<string, Type> catComponents = Mgr<TypeManager>.Singleton.CatComponents;
            if (catComponents != null)
            {
                foreach (KeyValuePair<string, Type> key_value in catComponents)
                {
                    ToolStripMenuItem item = new ToolStripMenuItem();
                    item.Text = key_value.Key;
                    item.Click += menu_insert_component;
                    menu_component.DropDownItems.Add(item);
                }
            }  
		}

		public void SetGameEngine(GameEngine gameEngine)
		{
			m_gameEngine = gameEngine;
		}

		public Point GetRenderAreaSize()
		{
			return new Point(renderArea.Width, renderArea.Height);
		}

		public IntPtr GetRenderAreaHandle()
		{
			return renderArea.Handle;
		}

		void InitializeResourceList(String rootDirectory, ComboBox list)
		{
			list.Items.Clear();
			DirectoryInfo dirInfo = new DirectoryInfo(m_gameEngine.Content.RootDirectory + "/" + rootDirectory);
			if (!dirInfo.Exists)
			{
				Console.WriteLine("Resource directory " + m_gameEngine.Content.RootDirectory + "/" + rootDirectory +
					" does not exist.");
				return;
			}

			FileInfo[] files = dirInfo.GetFiles();
			foreach (FileInfo file in files)
			{
				string key = Path.GetFileNameWithoutExtension(file.Name);
				list.Items.Add(rootDirectory + "/" + key);
			}
		}

		protected override void OnClosed(EventArgs e)
		{
			base.OnClosed(e);
			Application.Exit();
		}

		private void renderArea_SizeChanged(object sender, EventArgs e)
		{
			if (m_gameEngine != null)
			{
				m_gameEngine.GameEngine_SizeChanged();
			}
		}

		public void UpdateGameObjectList(GameObjectList sceneGameObjectList)
		{
			// TODO: add or minus one?
			gameObjectList.BeginInvoke(
                new UpdateGameObjectListDelegate(UpdateGameObjectList_u), new object[] { sceneGameObjectList });
		}

        delegate void UpdateGameObjectListDelegate(GameObjectList sceneGameObjectList);
        private void UpdateGameObjectList_u(GameObjectList sceneGameObjectList)
		{
			gameObjectList.Items.Clear();
            foreach (KeyValuePair<string, GameObject> keyValue in sceneGameObjectList.m_list)
			{
				gameObjectList.Items.Add(keyValue.Value);
			}
			gameObjectList.Refresh();
		}

		public void UpdateSceneAttribute(Scene scene)
		{
			attr_tab_scene.BeginInvoke(
				new UpdateSceneAttributeDelegate(UpdateSceneAttribute_u), new object[] { scene });
		}

		delegate void UpdateSceneAttributeDelegate(Scene scene);
		private void UpdateSceneAttribute_u(Scene scene)
		{


			attr_tab_scene.Refresh();
		}

		public void UpdateModelList(Dictionary<String, CatsModel> models)
		{
			modelList.BeginInvoke(
				new UpdateModelListDelegate(UpdateModelList_u), new object[] {models});
		}

		delegate void UpdateModelListDelegate(Dictionary<String, CatsModel> models);
        private void UpdateModelList_u(Dictionary<String, CatsModel> models)
		{
			modelList.Items.Clear();
            foreach (KeyValuePair<String, Catsland.Core.CatsModel> pair in models)
			{
				modelList.Items.Add(pair.Key);
			}
			modelList.Refresh();
		}

		public void UpdateMaterialList(Dictionary<String, Material> materials)
		{
			modelList.BeginInvoke(
				new UpdateMaterialListDelegate(UpdateMaterialList_u), new object[] { materials });
		}

		delegate void UpdateMaterialListDelegate(Dictionary<String, Material> models);
		private void UpdateMaterialList_u(Dictionary<String, Material> materials)
		{
			materialList.Items.Clear();
			foreach (KeyValuePair<String, Material> pair in materials)
			{
				materialList.Items.Add(pair.Key);
			}
			materialList.Refresh();
		}

		// return:
		// 0 - ok
		// 1 - existed
		int AddGameObjectToPrefabs(GameObject gameObject, bool isOverride = false)
		{
            PrefabList scenePrefabList = Mgr<Scene>.Singleton._prefabList;
			if (scenePrefabList.ContainKey(gameObject.Name))
			{
				if(isOverride == false)
				{
					return 1;
				}
				else
				{
                    scenePrefabList.RemoveItem(gameObject.Name);
				}
			}

			GameObject newGameObject = gameObject.CloneGameObject();
            scenePrefabList.AddItem(newGameObject.Name, newGameObject);
			return 0;
		}


        public void UpdatePrefabList(PrefabList scenePrefabList)
        {
            prefabList.Items.Clear();
            if (scenePrefabList != null && scenePrefabList.m_list != null)
            {
                foreach (KeyValuePair<string, GameObject> keyValue in scenePrefabList.m_list)
                {
                    prefabList.Items.Add(keyValue.Key);
                }
            }
            prefabList.Update();
        }


		private void gameObjectList_MouseDoubleClick(object sender, MouseEventArgs e)
		{
			GameObject selected = (GameObject)(gameObjectList.SelectedItem);
            AddGameObjectToPrefabs_Agent(selected);
			
		}

        private void AddGameObjectToPrefabs_Agent(GameObject gameObject)
        {
            if (gameObject != null)
            {
                int result = AddGameObjectToPrefabs(gameObject);
                if (result == 1) // existed
                {
                    if (MessageBox.Show(gameObject.Name + " Prefab exits, overwrite?",
                        "Overwrite?", MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        AddGameObjectToPrefabs(gameObject, true);
                    }
                }
            }
        }

        public void GameObjectNameChanged()
        {
            UpdateGameObjectList(Mgr<Scene>.Singleton._gameObjectList);
        }

		private void renderArea_Click(object sender, EventArgs e)
		{
            renderArea.Focus();
		}

        public void ComponentUpdate(object sender, EventArgs e)
        {
            ((CatComponent)((PackableBox)sender).ExtraData).Initialize(Mgr<Scene>.Singleton);
        }

        public void ComponentRemove(object sender, EventArgs e)
        {
            CatComponent catComponent = (CatComponent)((PackableBox)sender).ExtraData;
            GameObject gameObject = catComponent.m_gameObject;
            gameObject.RemoveComponent(catComponent.GetType().Name);
            UpdateGameObjectAttribute(m_observingGameObject);
        }

        public void UpdateGameObjectAttribute(GameObject gameObject)
        {
            attr_tab_newgo.Controls.Clear();
            m_observingGameObject = gameObject;

            if (m_observingGameObject != null )
            {
                PackableBox packableBox = new PackableBox();
                packableBox.Dock = DockStyle.Top;
                packableBox.AutoSize = true;
                packableBox.Text = "GameObject";
                packableBox.SetButtonVisible = false;
                
                PropertyGrid propertyGrid = new PropertyGrid();
                propertyGrid.SelectedObject = m_observingGameObject;
                propertyGrid.Dock = DockStyle.Top;
                propertyGrid.HelpVisible = false;

                packableBox.AddContent(propertyGrid);
                attr_tab_newgo.Controls.Add(packableBox);
                
                if(m_observingGameObject.GetComponentList() != null)
                {
                    foreach (KeyValuePair<string, CatComponent> key_value in 
                    m_observingGameObject.GetComponentList())
                    {
                        packableBox = new PackableBox();
                        packableBox.Dock = DockStyle.Top;
                        packableBox.AutoSize = true;
                        packableBox.Text = key_value.Key;
                        packableBox.ExtraData = key_value.Value;
                        packableBox.UpdateHappen += ComponentUpdate;
                        packableBox.RemoveHappen += ComponentRemove;

                        propertyGrid = new PropertyGrid();
                        propertyGrid.SelectedObject = key_value.Value;
                        propertyGrid.Text = key_value.Key;
                        propertyGrid.Dock = DockStyle.Top;
                        propertyGrid.HelpVisible = false;

                        packableBox.AddContent(propertyGrid);
                        attr_tab_newgo.Controls.Add(packableBox);
                    }
                }
                
                
            }
        }

		private void gameObjectList_MouseClick(object sender, MouseEventArgs e)
		{
			attr_tab.SelectTab(attr_tab_newgo);
			GameObject selected = (GameObject)(gameObjectList.SelectedItem);
			if (selected != null)
			{
				UpdateGameObjectAttribute(selected);
			}
		}

        /*
		private void attr_go_name_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_name = attr_go_name.Text;
				gameObjectList.Items.Remove(m_observingGameObject);
				gameObjectList.Items.Add(m_observingGameObject);
				gameObjectList.Refresh();
				//UpdateGameObjectList_u();
			}
		}
        */
        
		private void float_only_KeyPress(KeyPressEventArgs e)
		{
			if (e.KeyChar != '\b' && e.KeyChar != 13)
			{
				if (((e.KeyChar < '0') || (e.KeyChar > '9')) 
					&& (e.KeyChar != '.')
					&& (e.KeyChar != '-'))
				{
					e.Handled = true;
				}
			}
		}

		private void positive_only_KeyPress(KeyPressEventArgs e)
		{
			if (e.KeyChar != '\b' && e.KeyChar != 13)
			{
				if ((e.KeyChar < '0') || (e.KeyChar > '9'))
				{
					e.Handled = true;
				}
			}
		}

        // new gameObject
		private void toolStripButton1_Click(object sender, EventArgs e)
		{
			// create a gameObject in the center of screen
			GameObject newGameObject = new GameObject();
			newGameObject.Position = Vector2.Zero;
			newGameObject.Height = 0.0f;
			Mgr<Scene>.Singleton._gameObjectList.AddItem(newGameObject._guid, newGameObject);
			Mgr<Scene>.Singleton._debugDrawableList.AddItem(newGameObject);

		}

        // exit
		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Application.Exit();
		}

        // insert components
		private void insertToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
		{
			if (m_observingGameObject == null)
			{
				menu_component.Enabled = false;
			}
			else
			{
				menu_component.Enabled = true;
			}
		}
     
        /*
		private void menu_insert_model_Click(object sender, EventArgs e)
		{
			m_observingGameObject.m_model = new CatsModel("undefined", null);
			UpdateGameObjectAttribute(m_observingGameObject);
		}

        
		private void menu_insert_quadrender_Click(object sender, EventArgs e)
		{
			if(m_observingGameObject.m_model == null
				|| m_observingGameObject.m_model.m_material == null)
			{
				MessageBox.Show("QuadRender needs Model component with Material.",
					"Missing Component",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error,
					MessageBoxDefaultButton.Button1);
			}
			else
			{
				m_observingGameObject.m_quadRender = new QuadRender(m_observingGameObject);
				m_observingGameObject.m_quadRender.Initialize(Mgr<Scene>.Singleton);
				UpdateGameObjectAttribute(m_observingGameObject);
			}
		}
        */
        /*
		private void attr_ani_clipname_SelectedIndexChanged(object sender, EventArgs e)
		{
			m_observingGameObject.m_animator.CheckPlayAnimation(attr_ani_clipname.Text);
		}

		private void attr_ani_play_Click(object sender, EventArgs e)
		{
			m_observingGameObject.m_animator.PlayAnimation(attr_ani_clipname.Text);
		}

		private void attr_ani_stop_Click(object sender, EventArgs e)
		{
			m_observingGameObject.m_animator.Pause();
		}

		private void attr_ani_mirror_CheckedChanged(object sender, EventArgs e)
		{
			m_observingGameObject.m_animator.m_isMirror = attr_ani_mirror.Checked;
		}

		private void menu_insert_animator_Click(object sender, EventArgs e)
		{
			if(m_observingGameObject.m_model == null 
				|| m_observingGameObject.m_model.m_animation == null
				|| m_observingGameObject.m_quadRender == null)
			{
				MessageBox.Show("Animator needs the following component:\n"
					+ "1. Model component with Animation\n"
					+ "2. QuadRender component.",
					"Missing Component",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error,
					MessageBoxDefaultButton.Button1);
			}
			else
			{
				m_observingGameObject.m_animator = new Animator(m_observingGameObject);
				m_observingGameObject.m_animator.Initialize(Mgr<Scene>.Singleton);
				UpdateGameObjectAttribute(m_observingGameObject);
			}
		}

		private void menu_insert_collider_Click(object sender, EventArgs e)
		{
			if (m_observingGameObject == null)
			{
				MessageBox.Show("Component needs GameObject to add on",
					"Missing GameObject",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error,
					MessageBoxDefaultButton.Button1);
			}
			else
			{
				m_observingGameObject.m_collider = new Collider(m_observingGameObject);
				BoundingBox boundingBox = new BoundingBox();
				boundingBox.UpdateBoundFromRectangle();
				m_observingGameObject.m_collider.m_rootBounding = boundingBox;
				m_observingGameObject.m_collider.Initialize(Mgr<Scene>.Singleton);
				UpdateGameObjectAttribute(m_observingGameObject);
			}
		}

         * 
		private void attr_col_xmin_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_collider.m_rootBounding.m_XBound.X =
					float.Parse(attr_col_xmin.Text);
				m_observingGameObject.m_collider.m_rootBounding.UpdateBoundFromRectangle();
				m_observingGameObject.m_collider.UpdateDebugBound();
			}
		}

		private void attr_col_xmax_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_collider.m_rootBounding.m_XBound.Y =
					float.Parse(attr_col_xmax.Text);
				m_observingGameObject.m_collider.m_rootBounding.UpdateBoundFromRectangle();
				m_observingGameObject.m_collider.UpdateDebugBound();
			}
		}

		private void attr_col_ymin_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_collider.m_rootBounding.m_YBound.X =
					float.Parse(attr_col_ymin.Text);
				m_observingGameObject.m_collider.m_rootBounding.UpdateBoundFromRectangle();
				m_observingGameObject.m_collider.UpdateDebugBound();
			}
		}

		private void attr_col_ymax_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_collider.m_rootBounding.m_YBound.Y =
					float.Parse(attr_col_ymax.Text);
				m_observingGameObject.m_collider.m_rootBounding.UpdateBoundFromRectangle();
				m_observingGameObject.m_collider.UpdateDebugBound();
			}
		}

		private void attr_col_zmin_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_collider.m_rootBounding.m_heightRange.X =
					float.Parse(attr_col_zmin.Text);
				m_observingGameObject.m_collider.m_rootBounding.UpdateBoundFromRectangle();
				m_observingGameObject.m_collider.UpdateDebugBound();
			}
		}

		private void attr_col_zmax_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_collider.m_rootBounding.m_heightRange.Y =
					float.Parse(attr_col_zmax.Text);
				m_observingGameObject.m_collider.m_rootBounding.UpdateBoundFromRectangle();
				m_observingGameObject.m_collider.UpdateDebugBound();
			}
		}

		private void attr_col_istrigger_CheckedChanged(object sender, EventArgs e)
		{
			if(attr_col_istrigger.Checked)
			{
				m_observingGameObject.m_collider.m_colliderType = Collider.ColliderType.PositiveTrigger;
			}
			else
			{
				m_observingGameObject.m_collider.m_colliderType = Collider.ColliderType.Collider;
			}
		}

		private void attr_pe_esizex_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_emitterSize.X =
					float.Parse(attr_pe_esizex.Text);
			}
		}

		private void attr_pe_esizey_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_emitterSize.Y =
					float.Parse(attr_pe_esizey.Text);
			}
		}

		private void attr_pe_esizez_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_emitterSize.Z =
					float.Parse(attr_pe_esizez.Text);
			}
		}

		private void attr_pe_eoffsetx_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_emitterOffset.X =
					float.Parse(attr_pe_eoffsetx.Text);
			}
		}

		private void attr_pe_eoffsety_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_emitterOffset.Y =
					float.Parse(attr_pe_eoffsety.Text);
			}
		}

		private void attr_pe_eoffsetz_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_emitterOffset.Z =
					float.Parse(attr_pe_eoffsetz.Text);
			}
		}

		private void attr_pe_generaterate_KeyPress(object sender, KeyPressEventArgs e)
		{
			positive_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_generateRate =
					int.Parse(attr_pe_generaterate.Text);
			}
		}

		private void attr_pe_apply_Click(object sender, EventArgs e)
		{
			m_observingGameObject.m_paricleEmitter.m_maxParticles =
				int.Parse(attr_pe_maxparticle.Text);
			m_observingGameObject.m_paricleEmitter.Initialize(Mgr<Scene>.Singleton);
		}

		private void attr_pe_maxparticle_KeyPress(object sender, KeyPressEventArgs e)
		{
			positive_only_KeyPress(e);
		}

		private void attr_pe_dir_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				ParticleEmitter particleEmitter = m_observingGameObject.m_paricleEmitter;
				particleEmitter.SetVelocityDirection(
					new Vector3(float.Parse(attr_pe_dirx.Text),
							float.Parse(attr_pe_diry.Text),
							float.Parse(attr_pe_dirz.Text)));

				attr_pe_dirx.Text = "" + particleEmitter.m_VelocityDirection.X;
				attr_pe_diry.Text = "" + particleEmitter.m_VelocityDirection.Y;
				attr_pe_dirz.Text = "" + particleEmitter.m_VelocityDirection.Z;
			}
		}

		private void attr_pe_speed_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_speed =
					float.Parse(attr_pe_speed.Text);
			}
		}

		private void attr_pe_speedbias_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_speedBiaz =
					float.Parse(attr_pe_speedbias.Text);
			}
		}

		private void attr_pe_anglebias_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.SetVelocityBias(
					float.Parse(attr_pe_anglebias.Text));
			}
		}

		private void attr_pe_psizex_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_particleSize.X =
					float.Parse(attr_pe_psizex.Text);
			}
		}

		private void attr_pe_psizey_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_particleSize.Y =
					float.Parse(attr_pe_psizey.Text);
			}
		}

		private void attr_pe_life_KeyPress(object sender, KeyPressEventArgs e)
		{
			positive_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingGameObject.m_paricleEmitter.m_lifetime =
					int.Parse(attr_pe_life.Text);
			}
		}

		private void attr_pe_emit_CheckedChanged(object sender, EventArgs e)
		{
			m_observingGameObject.m_paricleEmitter.m_isEmitting
				= attr_pe_emit.Checked;
		}

		private void menu_insert_particleEmitter_Click(object sender, EventArgs e)
		{
			if (m_observingGameObject == null)
			{
				MessageBox.Show("Component needs GameObject",
					"Missing GameObject",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error,
					MessageBoxDefaultButton.Button1);
			}
			else
			{
				m_observingGameObject.m_paricleEmitter = new ParticleEmitter(m_observingGameObject);

				// find a material
				Material mtrl = null;
				foreach (KeyValuePair<String, Material> pair in
					Mgr<Scene>.Singleton.m_materialList.m_list)
				{
					mtrl = pair.Value;
					break;
				}
				if (mtrl == null)
				{
					MessageBox.Show("No available material.",
							"Error",
							MessageBoxButtons.OK,
							MessageBoxIcon.Error,
							MessageBoxDefaultButton.Button1);
				}
				else
				{
					m_observingGameObject.m_paricleEmitter.m_material = mtrl;
				}

				m_observingGameObject.m_paricleEmitter.Initialize(Mgr<Scene>.Singleton);
				UpdateGameObjectAttribute(m_observingGameObject);
			}
		}

		private void attr_pe_mtrl_SelectedIndexChanged(object sender, EventArgs e)
		{
			m_observingGameObject.m_paricleEmitter.m_material =
				Mgr<Scene>.Singleton.m_materialList.GetMaterial(attr_pe_mtrl.Text);
		}
        */
		private void modelList_MouseClick(object sender, MouseEventArgs e)
		{
			attr_tab.SelectTab(attr_tab_model);

			String modelName = (String)modelList.SelectedItem;
			if (modelName == null)
			{
				return;
			}
            Catsland.Core.CatsModel model = Mgr<Scene>.Singleton._modelList.GetModel(modelName);
			
			if (model != null)
			{
				UpdateModelAttribute(model);
			}
		}

        public void UpdateModelAttribute(Catsland.Core.CatsModel model)
		{
			m_observingModel = model;

			if (m_observingModel != null)
			{
				// name
				attr_ml_name.Text = m_observingModel._name;

				// material
				attr_ml_mtrl.Items.Clear();
				int index = 0;
				int iter = 0;
				foreach (String mtrl in materialList.Items)
				{
					attr_ml_mtrl.Items.Add(mtrl);
					if (mtrl == m_observingModel._material._name)
					{
						index = iter;
					}
					++iter;
				}
				if (materialList.Items.Count > 0)
				{
					attr_ml_mtrl.SelectedIndex = index;
				}
				m_observingModel._material._name = (String)attr_ml_mtrl.SelectedItem;
				

				// animaition and animation clips
				attr_ani_clips.Controls.Clear();
				Animation animation = m_observingModel._animation;
				if (animation != null)
				{
					attr_ani_mpf.Text = "" + animation._millionSecondPerFrame;
					attr_ani_tiltwidth.Text = "" + animation._tiltUV.X;
					attr_ani_tiltheight.Text = "" + animation._tiltUV.Y;
					attr_ani_autoplay.Checked = animation._isAutoPlay;

					index = 0;
					iter = 0;

					attr_ani_defaultclip.Items.Clear();
					foreach (KeyValuePair<String,AnimationClip> pair 
						in animation._animationClips)
					{
						if (pair.Key == animation._defaultAnimationClipName)
						{
							index = iter;
						}
						attr_ani_defaultclip.Items.Add(pair.Key);
						++iter;

						AnimationClipViewer animationClipViewer =
							new AnimationClipViewer();
						animationClipViewer.m_targetClip = pair.Value;
						animationClipViewer.ClipName = pair.Key;
						animationClipViewer.MinIndex = pair.Value._beginIndex;
						animationClipViewer.MaxIndex = pair.Value._endIndex;
						animationClipViewer.ClipMode = (int)pair.Value._mode;

						animationClipViewer.ClipNameChanged +=
							new AnimationClipViewer.ClipNameChangedEventHandler(animationClipViewer_ClipNameChanged);
						animationClipViewer.MinIndexChanged +=
							new AnimationClipViewer.MinIndexChangedEventHandler(animationClipViewer_MinIndexChanged);
						animationClipViewer.MaxIndexChanged +=
							new AnimationClipViewer.MaxIndexChangedEventHandler(animationClipViewer_MaxIndexChanged);
						animationClipViewer.ClipModeChanged +=
							new AnimationClipViewer.ClipModeChangedEventHandler(animationClipViewer_ClipModeChanged);
						animationClipViewer.DeleteButtonClicked +=
							new AnimationClipViewer.DeleteButtonClickedEventHandler(animationClipViewer_DeleteButtonClicked);

						animationClipViewer.Dock = DockStyle.Top;
						attr_ani_clips.Controls.Add(animationClipViewer);	
					}
					if (attr_ani_defaultclip.Items.Count > 0)
					{
						attr_ani_defaultclip.SelectedIndex = index;
					}

				}


				// show all tab
				attr_ml_name.Visible = true;
				attr_mtl_group.Visible = true;
				attr_clips_group.Visible = true;
			}
			else
			{
				// hide all tab
				attr_ml_name.Visible = false;
				attr_mtl_group.Visible = false;
				attr_clips_group.Visible = false;
			}

		}

		private void animationClipViewer_ClipModeChanged(object sender, EventArgs e)
		{
			AnimationClipViewer animationClipViewer =
				sender as AnimationClipViewer;
			AnimationClip animationClip =
				animationClipViewer.m_targetClip as AnimationClip;
			animationClip._mode = PlayModeLUT[animationClipViewer.ClipMode];
		}

		private void animationClipViewer_ClipNameChanged(object sender, EventArgs e)
		{
			AnimationClipViewer animationClipViewer =
				sender as AnimationClipViewer;
			AnimationClip animationClip =
				animationClipViewer.m_targetClip as AnimationClip;

			// find duplicate
			String name = animationClipViewer.ClipName;
			AnimationClip replaced = m_observingModel._animation.getAnimationClip(name);
			if (replaced == null)
			{
				m_observingModel._animation._animationClips.Remove(animationClip._name);
				animationClip._name = name;
				m_observingModel._animation.addAnimationClip(animationClip);
			}
			UpdateModelAttribute(m_observingModel);
		}

		private void animationClipViewer_MaxIndexChanged(object sender, EventArgs e)
		{
			AnimationClipViewer animationClipViewer =
				sender as AnimationClipViewer;
			AnimationClip animationClip =
				animationClipViewer.m_targetClip as AnimationClip;
			animationClip._endIndex = animationClipViewer.MaxIndex;
		}

		private void animationClipViewer_MinIndexChanged(object sender, EventArgs e)
		{
			AnimationClipViewer animationClipViewer =
				sender as AnimationClipViewer;
			AnimationClip animationClip =
				animationClipViewer.m_targetClip as AnimationClip;
			animationClip._beginIndex = animationClipViewer.MinIndex;
		}

		private void animationClipViewer_DeleteButtonClicked(object sender, EventArgs e)
		{
			AnimationClipViewer animationClipViewer =
				sender as AnimationClipViewer;
			AnimationClip animationClip =
				animationClipViewer.m_targetClip as AnimationClip;
			attr_clips_group.Controls.Remove(animationClipViewer);
			m_observingModel._animation._animationClips.Remove(animationClip._name);
			UpdateModelAttribute(m_observingModel);
		}

		private void button1_Click(object sender, EventArgs e)
		{
			if (m_observingModel._animation == null)
			{
				m_observingModel._animation = new Animation();
			}
			int index = 1;
			String title = "untitled";
			while (m_observingModel._animation.getAnimationClip(title + index) != null)
			{
				++index;
			}
			
			AnimationClip animationClip = new AnimationClip(title + index);
			m_observingModel._animation.addAnimationClip(animationClip);
			UpdateModelAttribute(m_observingModel);
		}

		private void attr_ani_mpf_KeyPress(object sender, KeyPressEventArgs e)
		{
			positive_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingGameObject != null)
			{
				m_observingModel._animation._millionSecondPerFrame =
					int.Parse(attr_ani_mpf.Text);
			}
		}

		private void attr_ani_tilt_KeyPress(object sender, KeyPressEventArgs e)
		{
			positive_only_KeyPress(e);
			if (e.KeyChar == 13 && m_observingModel != null)
			{
				m_observingModel._animation._tiltUV =
					new Point(int.Parse(attr_ani_tiltwidth.Text),
							int.Parse(attr_ani_tiltheight.Text));
			}
		}

		private void attr_ani_autoplay_CheckedChanged(object sender, EventArgs e)
		{
			m_observingModel._animation._isAutoPlay = attr_ani_autoplay.Checked;
		}

		private void attr_ani_defaultclip_SelectedIndexChanged(object sender, EventArgs e)
		{
			m_observingModel._animation._defaultAnimationClipName =
				(String)attr_ani_defaultclip.SelectedItem;
		}

		private void attr_ml_name_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar == 13)
			{
				// judge if the name duplicate
				String newName = attr_ml_name.Text;
				ModelList list = Mgr<Scene>.Singleton._modelList;
                Catsland.Core.CatsModel model = list.GetModel(newName);
				if (model == null)
				{
					list.m_list.Remove(m_observingModel._name);
					m_observingModel._name = newName;
					list.AddModel(m_observingModel);
				}
				else if (model != m_observingModel) // duplicate, reset
				{
					MessageBox.Show("Duplicate model name.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_ml_name.Text = m_observingModel._name;
					attr_ml_name.Refresh();
				}
				// else, just same as original
			}
		}

		private void toolStripButton2_Click(object sender, EventArgs e)
		{
			// find title
			String title = "Untitled";
			int index = 1;
			ModelList list = Mgr<Scene>.Singleton._modelList;
			while (list.GetModel(title + index) != null)
			{
				++index;
			}

			// find material
			Material mtrl = null;
			foreach(KeyValuePair<String, Material> pair in
				Mgr<Scene>.Singleton._materialList.m_list)
				{
				mtrl = pair.Value;
				break;
			}
			if (mtrl == null)
			{
				MessageBox.Show("No available material.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
			}
			else
			{
                Catsland.Core.CatsModel newModel = new Catsland.Core.CatsModel(title + index, mtrl);
				list.AddModel(newModel);
			}
		}

		void UpdateMaterialAttribute(Material material)
		{
			m_observingMaterial = material;
			if (m_observingMaterial != null)
			{
				// show tab
				attr_tab.SelectTab(attr_tab_material);
				attr_mtrl_name.Text = m_observingMaterial._name;

				// texture
				int index = 0;
				int iter = 0;
				foreach (String mtrl in attr_mtrl_texture.Items)
				{
					if (mtrl == m_observingMaterial._texture.Name)
					{
						index = iter;
					}
					++iter;
				}
				if (attr_mtrl_texture.Items.Count > 0)
				{
					attr_mtrl_texture.SelectedIndex = index;
				}
				

				// effect
				index = 0;
				iter = 0;

				Console.WriteLine("Effect " + m_observingMaterial._effect.Name);
				foreach (String effect in attr_mtrl_effect.Items)
				{
					if (effect == m_observingMaterial._effect.Name)
					{
						index = iter;
					}
					++iter;
				}
				if (attr_mtrl_effect.Items.Count > 0)
				{
					attr_mtrl_effect.SelectedIndex = index;
				}

				attr_tab_material.Refresh();	
			}
		}

		private void materialList_MouseClick(object sender, MouseEventArgs e)
		{
			if (materialList.SelectedItem == null)
			{
				return;
			}
			Material mtrl = 
				(Material)(Mgr<Scene>.Singleton._materialList.GetMaterial((String)materialList.SelectedItem));
			UpdateMaterialAttribute(mtrl);
		}

		private void attr_mtrl_name_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar == 13)
			{
				// judge if the name duplicate
				String newName = attr_mtrl_name.Text;
				MaterialList list = Mgr<Scene>.Singleton._materialList;
				Material material = list.GetMaterial(newName);
				if (material == null)
				{
					list.m_list.Remove(m_observingMaterial._name);
					m_observingMaterial._name = newName;
					list.AddMaterial(m_observingMaterial);
				}
				else if (material != m_observingMaterial) // duplicate, reset
				{
					MessageBox.Show("Duplicate material name.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_mtrl_name.Text = m_observingMaterial._name;
					attr_mtrl_name.Refresh();
				}
				// else, just same as original
			}
		}

		private void attr_mtrl_texture_SelectedIndexChanged(object sender, EventArgs e)
		{
			String texture = (String)attr_mtrl_texture.SelectedItem;

			m_observingMaterial._texture =
				Mgr<Scene>.Singleton._contentManager.Load<Texture2D>(texture);
			m_observingMaterial._texture.Name = texture;
		}

		// TODO: add effect

		bool SaveScene(String filename)
		{
			// header
			XmlDocument doc = new XmlDocument();
			XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
			doc.AppendChild(dec);

			// scene
			Mgr<Scene>.Singleton.SaveToNode(doc, doc);

			doc.Save(filename);
			return true;
		}

		bool OpenScene(String filename)
		{
			XmlDocument doc = new XmlDocument();
			doc.Load(filename);

			XmlNode scene = doc.SelectSingleNode("Scene");
			// create new scene a load
			Scene newScene = Scene.LoadFromNode(scene, m_gameEngine);
			newScene.InitializeScene();
			newScene.ActivateScene();
			Mgr<Scene>.Singleton = newScene;

            pg_scene.SelectedObject = newScene;
			return true;
		}

		private void saveSceneToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SaveFileDialog saveFileDialog = new SaveFileDialog();
			saveFileDialog.Filter = "Catland Map|*.xml";
			saveFileDialog.FilterIndex = 1;
			if (saveFileDialog.ShowDialog() == DialogResult.OK)
			{
				String filename = saveFileDialog.FileName;
				SaveScene(filename);
			}
		}

        private void playScene()
        {
            SaveScene(m_tmp_filename);
            m_gameEngine._gameInEditorMode = GameEngine.InEditorMode.Playing;
            btn_play.Enabled = false;
            btn_stop.Enabled = true;
            btn_pause.Enabled = true;
        }

        private void stopScene()
        {
            m_gameEngine._gameInEditorMode = GameEngine.InEditorMode.Editing;
            OpenScene(m_tmp_filename);
            btn_play.Enabled = true;
            btn_stop.Enabled = false;
            btn_pause.Enabled = false;
        }

        private void pauseScene()
        {
            if (m_gameEngine._gameInEditorMode == GameEngine.InEditorMode.Playing)
            {
                m_gameEngine._gameInEditorMode = GameEngine.InEditorMode.Editing;
            }
            else
            {
                m_gameEngine._gameInEditorMode = GameEngine.InEditorMode.Playing;
            }
        }

		private void loadSceneToolStripMenuItem_Click(object sender, EventArgs e)
		{
			OpenFileDialog openFileDialog = new OpenFileDialog();
			openFileDialog.Filter = "Catsland Map|*.xml";
			openFileDialog.FilterIndex = 1;
			if (openFileDialog.ShowDialog() == DialogResult.OK)
			{
				String filename = openFileDialog.FileName;
				OpenScene(filename);
                m_gameEngine._gameInEditorMode = GameEngine.InEditorMode.Editing;
                btn_play.Enabled = true;
                btn_stop.Enabled = false;
                btn_pause.Enabled = false;
                Mgr<Camera>.Singleton.Reset();
			}
		}

		private void toolStripButton3_Click(object sender, EventArgs e)
		{
			// find title
			String title = "Untitled";
			int index = 1;
			MaterialList list = Mgr<Scene>.Singleton._materialList;
			while (list.GetMaterial(title + index) != null)
			{
				++index;
			}

			// find texture
			Texture2D texture = null;
			foreach (String textureName in attr_mtrl_texture.Items)
			{
				texture = Mgr<Scene>.Singleton._contentManager.Load<Texture2D>(textureName);
			}
			if (texture == null)
			{
				MessageBox.Show("No available texture.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
				return;
			}

			// find effect
			// TODO find effect

			// combine
			Material material = new BasicEffectMaterial(title + index, Mgr<BasicEffect>.Singleton, texture);
			list.AddMaterial(material);
		}
/*
		private void attr_sc_xmin_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				float value = float.Parse(attr_sc_xmin.Text);
				if (value > Mgr<Scene>.Singleton._XBound.Y)
				{
					MessageBox.Show("X min should not be greater than X max.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_sc_xmin.Text = "" + value;
				}
				else
				{
					Mgr<Scene>.Singleton._XBound.X = value;
#if DEBUG
					Mgr<Scene>.Singleton.UpdateDebugVertex();
#endif
				}

			}
		}
*/
        /*
		private void attr_sc_xmax_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				float value = float.Parse(attr_sc_xmax.Text);
				if (value < Mgr<Scene>.Singleton._XBound.X)
				{
					MessageBox.Show("X max should not be less than X min.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_sc_xmax.Text = "" + value;
				}
				else
				{
					Mgr<Scene>.Singleton._XBound.Y = value;
#if DEBUG
					Mgr<Scene>.Singleton.UpdateDebugVertex();
#endif
				}
			}
		}
        */
        /*
		private void attr_sc_ymin_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				float value = float.Parse(attr_sc_ymin.Text);
				if (value > Mgr<Scene>.Singleton._YBound.Y)
				{
					MessageBox.Show("Y min should not be greater than Y max.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_sc_ymin.Text = "" + value;
				}
				else
				{
					Mgr<Scene>.Singleton._YBound.X = value;
#if DEBUG
					Mgr<Scene>.Singleton.UpdateDebugVertex();
#endif
				}
			}
		}

		private void attr_sc_ymax_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				float value = float.Parse(attr_sc_ymax.Text);
				if (value < Mgr<Scene>.Singleton._YBound.X)
				{
					MessageBox.Show("Y max should not be less than Y min.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_sc_ymax.Text = "" + value;
				}
				else
				{
					Mgr<Scene>.Singleton._YBound.Y = value;
#if DEBUG
					Mgr<Scene>.Singleton.UpdateDebugVertex();
#endif
				}
			}
		}

		private void attr_sc_zmin_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				float value = float.Parse(attr_sc_zmin.Text);
				if (value > Mgr<Scene>.Singleton._ZBound.Y)
				{
					MessageBox.Show("Z min should not be greater than Z max.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_sc_zmin.Text = "" + value;
				}
				else
				{
					Mgr<Scene>.Singleton._ZBound.X = value;
#if DEBUG
					Mgr<Scene>.Singleton.UpdateDebugVertex();
#endif
				}
			}
		}

		private void attr_sc_zmax_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				float value = float.Parse(attr_sc_zmax.Text);
				if (value < Mgr<Scene>.Singleton._ZBound.X)
				{
					MessageBox.Show("Z max should not be less than Z min.",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
					attr_sc_zmax.Text = "" + value;
				}
				else
				{
					Mgr<Scene>.Singleton._ZBound.Y = value;
#if DEBUG
					Mgr<Scene>.Singleton.UpdateDebugVertex();
#endif
				}
			}
		}

		private void attr_sc_view_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				float value = float.Parse(attr_sc_view.Text);
				if (value < 0.0f || value > 90.0f)
				{
					MessageBox.Show("View angle should be in [0.0, 90.0].",
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error,
						MessageBoxDefaultButton.Button1);
				}
				if (value < 0.0f)
				{
					attr_sc_view.Text = "" + 0;
				}
				if (value > 90.0f)
				{
					attr_sc_view.Text = "" + 90;
				}

				Mgr<Scene>.Singleton.setYAngle(value);
#if DEBUG
				Mgr<Scene>.Singleton.UpdateDebugVertex();
#endif
			}
		}
        */
		private void attr_ml_mtrl_SelectedIndexChanged(object sender, EventArgs e)
		{
			String materialName = (String)(attr_ml_mtrl.SelectedItem);
			m_observingModel._material = Mgr<Scene>.Singleton._materialList.GetMaterial(materialName);
		}

        /*
		private void attr_bgc_zoffset_KeyPress(object sender, KeyPressEventArgs e)
		{
			float_only_KeyPress(e);
			if (e.KeyChar == 13)
			{
				m_observingGameObject.m_backgroundController.m_zOffset =
					float.Parse(attr_bgc_zoffset.Text);
			}
		}

		private void backgroundControllerToolStripMenuItem1_Click(object sender, EventArgs e)
		{
			m_observingGameObject.m_backgroundController = 
				new BackgroundController(m_observingGameObject);
			UpdateGameObjectAttribute(m_observingGameObject);
		}

		private void characterControllerToolStripMenuItem1_Click(object sender, EventArgs e)
		{
			m_observingGameObject.m_characterController =
				new CharacterController(m_observingGameObject);
			m_observingGameObject.m_characterController.Initialize(Mgr<Scene>.Singleton);
			UpdateGameObjectAttribute(m_observingGameObject);
		}
         */ 
        /*
		private void keyboardInputToolStripMenuItem_Click(object sender, EventArgs e)
		{
			m_observingGameObject.m_inputer =
				new KeyboardInput(m_observingGameObject);
			m_observingGameObject.m_inputer.Initialize(Mgr<Scene>.Singleton);
			UpdateGameObjectAttribute(m_observingGameObject);
		}

		private void attr_bgc_adjusty_CheckedChanged(object sender, EventArgs e)
		{
			m_observingGameObject.m_backgroundController.m_yAdjust = attr_bgc_adjusty.Checked;
		}
        */

		private void button2_Click(object sender, EventArgs e)
		{
			Mgr<Camera>.Singleton.m_target = m_observingGameObject;
		}

        /*
		private void menu_insert_dialogresponser_Click(object sender, EventArgs e)
		{
			DialogResponser dialogResponser = new DialogResponser(m_observingGameObject);
			dialogResponser.Initialize(Mgr<Scene>.Singleton);
			m_observingGameObject.m_dialogResponser = dialogResponser;
			UpdateGameObjectAttribute(m_observingGameObject);
		}

		private void menu_insert_dialoganimator_Click(object sender, EventArgs e)
		{
			DialogAnimator dialogAnimator = new DialogAnimator(m_observingGameObject);
			dialogAnimator.Initialize(Mgr<Scene>.Singleton);
			m_observingGameObject.m_dialogAnimator = dialogAnimator;
			UpdateGameObjectAttribute(m_observingGameObject);
		}
        */

        /*
		private void button3_Click(object sender, EventArgs e)
		{
			DialogAnimator dialogAnimator = m_observingGameObject.m_dialogAnimator;
			dialogAnimator.AddDialog("Say something");
			UpdateGameObjectAttribute(m_observingGameObject);
		}
        */

		private void button4_Click(object sender, EventArgs e)
		{
			Mgr<Scene>.Singleton._player = m_observingGameObject;
		}

        private void editToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            deleteGameObjectToolStripMenuItem.Enabled = (m_observingGameObject != null);
            addGameObjectToPrefabToolStripMenuItem.Enabled = (m_observingGameObject != null);
            deleteProfabToolStripMenuItem.Enabled = (prefabList.SelectedItem != null);
        }

        private void deleteGameObjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_observingGameObject != null)
            {
                Mgr<Scene>.Singleton._gameObjectList.RemoveItem(m_observingGameObject._guid);
                m_observingGameObject = null;
                UpdateGameObjectAttribute(null);
            }

        }

        private void addGameObjectToPrefabToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_observingGameObject != null)
            {
                AddGameObjectToPrefabs_Agent(m_observingGameObject);
            } 
        }

        private void prefabList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            string prefabName = (string)prefabList.SelectedItem;    
            Insert_GameObject_From_Prefab(prefabName);

        }

        private void Insert_GameObject_From_Prefab(string prefabName)
        {
            PrefabList scenePrefabList = Mgr<Scene>.Singleton._prefabList;
            if( scenePrefabList.ContainKey(prefabName))
            {
                GameObject prefab = scenePrefabList.GetItem(prefabName);
                GameObject gameObject = prefab.CloneGameObject();
                //gameObject.Initialize(Mgr<Scene>.Singleton);
                Mgr<Scene>.Singleton._gameObjectList.AddItem(gameObject._guid, gameObject);
            }
            else
            {
                Console.Out.WriteLine("Could not find prefab named: " + prefabName);
            }    
        }

        private void deleteProfabToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string prefabName = (string)prefabList.SelectedItem;
            if (prefabName != null)
            {
                Mgr<Scene>.Singleton._prefabList.RemoveItem(prefabName);
            }
        }

        private void renderArea_Click_1(object sender, EventArgs e)
        {
            renderArea.Focus();
        }

        private void btn_play_Click(object sender, EventArgs e)
        {
            playScene();
        }

        private void btn_stop_Click(object sender, EventArgs e)
        {
            stopScene();
        }

        private void btn_pause_Click(object sender, EventArgs e)
        {
            pauseScene();
        }

        /*
		private void breakableToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Breakable breakable = new Breakable(m_observingGameObject);
			m_observingGameObject.m_breakable = breakable;
			UpdateGameObjectAttribute(m_observingGameObject);
		}
        */
	}
}
